package com.koron.css2.baseConfig.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.koron.css2.ApplicationConfig;
import com.koron.css2.ServerInterface;
import com.koron.css2.baseConfig.bean.EventPushBean;
import com.koron.css2.baseConfig.dto.EventPushDTO;
import com.koron.css2.baseConfig.mapper.EvaluationSendMapper;
import com.koron.css2.clientCenter.bean.CtmInfoBean;
import com.koron.css2.clientCenter.mapper.CtmInfoMapper;
import com.koron.css2.serviceManage.bean.RequestBean;
import com.koron.css2.serviceManage.bean.UserInfoBean;
import com.koron.util.Constant;
import com.koron.util.JsonUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.swan.bean.MessageBean;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * 好差评发送接口
 */
public class EvaluationSend implements ServerInterface {

    private static final Logger logger = LoggerFactory.getLogger(EvaluationSend.class);

    @Override
    public MessageBean<?> exec(SessionFactory factory, UserInfoBean userInfo, RequestBean req) {
        MessageBean<String> info = MessageBean.create(Constant.MESSAGE_INT_SUCCESS, "success", String.class);
        try {
            // 获取好差评发送信息
            EventPushBean eventPushBean = JsonUtils.objectToPojo(req.getData(), EventPushBean.class);
            // 处理数据
            eventPushBean.setDepartmentCode("12441500196720244T");
            eventPushBean.setDepartmentName("汕尾市供水总公司");
            eventPushBean.setEvalProcess(1);
            eventPushBean.setEvalTime(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            eventPushBean.setAffairApplyTime(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            eventPushBean.setAffairDoneTime(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            eventPushBean.setServiceTime(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            // 身份证号查询设置，前端传参客户编号
            if (eventPushBean.getCertificateNo() == null) {
                eventPushBean.setCertificateNo("xxxxxxxxxxxxxxxxxx");
            }else {
                String ctmNo = eventPushBean.getCertificateNo();
                CtmInfoMapper ctmMapper = factory.getMapper(CtmInfoMapper.class);
                CtmInfoBean ctmInfo = ctmMapper.getCtmInfoByCtmNo(ctmNo, CtmInfoBean.CTM);
                if (ctmInfo != null) {
                    String certNo = ctmInfo.getCertNo()!=null?ctmInfo.getCertNo():"";
                    if ("".equals(certNo)){
                        eventPushBean.setCertificateNo("xxxxxxxxxxxxxxxxxx");
                    }else {
                        eventPushBean.setCertificateNo(certNo);
                    }
                }else {
                    eventPushBean.setCertificateNo("xxxxxxxxxxxxxxxxxx");
                }
            }
            eventPushBean.setVersion("3.0");
            // 查询好差评发送信息的用户最后发送时间是否与当前时间大于一个月
            EvaluationSendMapper mapper = factory.getMapper(EvaluationSendMapper.class);
            EventPushDTO eventPushDTO = mapper.selectLastByUserName(eventPushBean.getUserName());
            String result = "";
            if (eventPushDTO == null) {
                // lastSendTime为空的处理逻辑
                result = sendEventPushData(eventPushBean);
                EventPushDTO newEventPushDTO = new EventPushDTO();
                BeanUtils.copyProperties(eventPushBean, newEventPushDTO);
                newEventPushDTO.setLastSendTime(new Date());
                logger.info("ready for sending...... ......");
                mapper.saveEvaluationPushInfo(newEventPushDTO);
            } else {
                Date lastSendTime = eventPushDTO.getLastSendTime();
                // 将 lastSendTime 转换为 LocalDateTime 对象
                LocalDateTime lastSendDateTime = lastSendTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                // 计算两个日期之间的间隔
                Period period = Period.between(lastSendDateTime.toLocalDate(), LocalDate.now());
                // 检查是否间隔一个月或以上
                if (period.toTotalMonths() >= 1 || period.getYears() > 0) {
                    // 间隔一个月或以上的处理逻辑
                    result = sendEventPushData(eventPushBean);
                    EventPushDTO newEventPushDTO = new EventPushDTO();
                    BeanUtils.copyProperties(eventPushBean, newEventPushDTO);
                    newEventPushDTO.setLastSendTime(new Date());
                    logger.info("ready for sending...... ......");
                    mapper.saveEvaluationPushInfo(newEventPushDTO);
                }else {
                    info.setDescription("该用户评价间隔不足一个月不发送好差评");// 间隔不足一个月不发送好差评
                }
            }
            info.setData("发送成功，"+result);
        } catch (Exception e) {
            logger.error("发送数据异常", e);
            return MessageBean.create(Constant.MESSAGE_INT_FAIL, "好差评发送数据异常", Void.class);
        }
        return info;
    }

    // 发送好差评数据的方法
    private String sendEventPushData(EventPushBean eventPushBean) {
        try {
            // 将实体类转换成字符串数据
            ObjectMapper objectMapper = new ObjectMapper();
            String text = "["+objectMapper.writeValueAsString(eventPushBean)+"]";
            // 加密数据
            logger.info("========================================");
            logger.info("The data before encryption is ："+text);
            String postData = encryptData(text);
            logger.info("The encrypted data is ："+postData);
            logger.info("========================================");
            // 发送数据
            String url = ApplicationConfig.getGovernmentHallWebsite();
            if (url == null) {
                logger.error("url is null,Need to configure in the configuration file");
                url = "http://shanwei2.hyruanjian.cn/OutInterface/EventCompleted";
            }
            String responseCode = sendPostRequest(url, postData);
            logger.info("The responseCode is :"+responseCode);
            return responseCode+"加密后编码为:"+postData;
        } catch (Exception e) {
            throw new RuntimeException("好差评发送数据异常", e);
        }
    }

    private String encryptData(String data) throws Exception {
        String key = "swhcp2020";// 秘钥
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        String keyMd5 = padLeft(toHexString(md5.digest(key.getBytes())), 32, '0');
        String ky = keyMd5.substring(0, 24);
        String iv = keyMd5.substring(24);
        SecretKey deskey = new SecretKeySpec(ky.getBytes(), "DESede");
        IvParameterSpec desIv = new IvParameterSpec(iv.getBytes());
        Cipher c1 = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        c1.init(Cipher.ENCRYPT_MODE, deskey, desIv);
        // 加密后的字符串
        byte[] encryptedBytes = c1.doFinal(data.getBytes("GBK"));
        return toHexString(encryptedBytes);
    }

    private String sendPostRequest(String url, String postData) throws IOException {
        // 创建URL对象
        URL requestUrl = new URL(url);
        // 打开连接
        HttpURLConnection connection = (HttpURLConnection) requestUrl.openConnection();
        connection.setRequestMethod("POST");
        connection.setDoOutput(true);
        // 设置Content-Type和Content-Length头部
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("Content-Length", String.valueOf(postData.length()));
        // 将POST数据写入连接的输出流
        try (OutputStream outputStream = connection.getOutputStream()) {
            outputStream.write(postData.getBytes(StandardCharsets.UTF_8));
            outputStream.flush();
        }
        // 获取响应码
        int responseCode = connection.getResponseCode();
        // 读取响应数据
        StringBuilder response = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
        }
        // 关闭连接
        connection.disconnect();
        return responseCode + response.toString();
    }


    /**
     * 字节数组转成16进制表示格式的字符串
     * @param byteArray 需要转换的字节数组
     * @param  joinStr 连接的字符
     * @return 16进制表示格式的字符串
     **/
    public static String toHexString(byte[] byteArray,String joinStr) {
        if (byteArray == null || byteArray.length < 1) {
            throw new IllegalArgumentException("this byteArray must not be null or empty");
        }

        final StringBuilder hexString = new StringBuilder();
        boolean joinStrIsEmpty= isEmpty(joinStr);
        for (int i = 0; i < byteArray.length; i++) {
            hexString.append(String.format("%02X",byteArray[i]));

            if (!joinStrIsEmpty && i < byteArray.length - 1) {
                hexString.append(joinStr);
            }
        }

        return hexString.toString();
    }

    /**
     * 字节数组转成16进制表示格式的字符串，无间隔字串
     * @param byteArray 需要转换的字节数组
     * @return 16进制表示格式的字符串
     */
    public static String toHexString(byte[] byteArray) {
        return toHexString(byteArray,"");
    }


    /**
     * 补齐字符串
     */
    public static String padLeft(String text, int len, char c) {
        if (null == text) {
            text = "";
        }
        int curLen = text.length();
        if (curLen < len) {
            StringBuilder sb = new StringBuilder(len);
            for (int i = 0; i < len - curLen; i++) {
                sb.append(c);
            }
            sb.append(text);
            text = sb.toString();
        }
        return text;
    }


    /**
     * 判定指定的字串是否为空
     */
    public static boolean isEmpty(String str) {
        return null==str || str.length()<1;
    }
}
